<?php

namespace Partner\Model;

use Utuo\UtuoModel;

class CommonTreeModel extends UtuoModel {
	
	// 数据表中标识记录所有者的字段
	protected $adminField = 'partner'; 
	
	/**
	 * 获取分类详细信息
	 * 
	 * @param milit $id 分类ID或标识
	 * @param boolean $field 查询字段
	 * @return array 分类信息
	 */
	public function info($id, $field = true) {
		$map = array ();
		if (is_numeric ( $id )) { // 通过ID查询
			$map ['id'] = $id;
		} else { // 通过标识查询
			$map ['name'] = $id;
		}
		return $this->field ( $field )->where ( $map )->find ();
	}
	
	/**
	 * 获取分类树，指定分类则返回指定分类极其子分类，不指定则返回所有分类树
	 * 
	 * @param integer $id 分类ID
	 * @param boolean $field 查询字段
	 * @return array 分类树
	 */
	public function getTree($id = 0, $partner = 0, $field = true) {
		if ($id) {
			$info = $this->info ( $id );
			$id = $info ['id'];
		}
		$map = array (
				'partner' => $partner,
				'is_deleted' => 0 
		);
		$list = $this->field ( $field )->where ( $map )->order ( 'sort' )->select ();
		$listNew = array ();
		$tabTree = \Utuo\TabTree::newInstance ();
		$tabTree->listToTree ( $list, $pk = 'id', $pid = 'pid', $child = '_', $root = $id, $listNew );
		$listNew = empty ( $listNew ) ? $listNew : $listNew ['_'];
		if (isset ( $info )) { // 指定分类则返回当前分类极其子分类
			$info ['_'] = $listNew;
		} else { // 否则返回所有分类
			$info = $listNew;
		}
		return $info;
	}
	
	/**
	 * 获得树列表
	 * 
	 * @param unknown $tree        	
	 * @return Ambigous <multitype:, array, unknown>
	 */
	public function getTreeList($tree) {
		$tabTree = \Utuo\TabTree::newInstance ();
		return $tabTree->treeToList ( $tree, $child = '_', $order = 'id' );
	}
	
	/**
	 * 数据库树结构更新(父结点改变时调用)
	 * 
	 * @param map $category 先前栏目数据
	 * @param string $fields 要获得的字段(，号间隔)
	 * @return boolean
	 */
	public function changeParentNode($category, $fields) {
		$newData = $this->data;
		
		/* 验证修改后的栏目是否子级 */
		$tree = $this->getTree ( 0, $category ['partner'], $fields );
		
		function checkNode($old_pid, $new_pid, $now, $flag) {
			foreach ( $now as $k => $v ) {
				
				if ($v ["id"] == $old_pid) {
					
					$flag = true; // 设置开始查找标识
					
					$now_pid = $v ["pid"];
				}
				
				if ($flag && ($v ["pid"] === $now_pid) && $v ["id"] != $old_pid) { // 已退出同级子树重设标识
					
					$flag = false;
					
					return false;
				}
				
				if ($flag && ($v ["id"] == $new_pid)) {
					
					return true;
				} else {
					
					if ($v ["_"])
						checkNode ( $old_pid, $new_pid, $v ["_"], $flag );
				}
			}
		}
		
		if (checkNode ( $category ['pid'], $newData ['pid'], $tree, false )) {
			
			$this->error = "新指定的父栏不能为当前栏目或其子级.";
			
			return false;
		}
		
		/* 更新原有父栏信息 */
		if (! $this->where ( 'pid=%d and id!=%d', $category ['pid'], $category ['id'] )->count ()) { // 当前父栏已没有子栏
			
			$this->where ( 'id=%d', $category ['pid'] )->setField ( 'has_child', 0 );

		}
		
		/* 设置当前指定的父栏有孩子 */
		$this->where ( 'id=%d', $newData ['pid'] )->setField ( 'has_child', 1 );
		
		/* 当前栏与子栏级别更新 */
		// 获得父栏信息
		if ( $newData ['pid'] ) {
			$cnode = $this->where ( "id=%d", $newData ['pid'] )->find();
			$pLevel = $cnode['level'];
			$parentPath = $cnode['path'];
		} else {
			$pLevel = -1;
			$parentPath = "0";
		}
		
		// 设置当前栏级别
		$this->where ( 'id=%d', $newData ['id'] )->save ( array( 'level' => ++$pLevel, 'path' => $parentPath.",{$newData['id']}" ) ); 
		
		$scope = $this;
		
		function refresh($nodes, $level, $path, $scope) {
			foreach ( $nodes as $v ) {
				$nodes = $scope->where("pid={$v['id']}")->select();
				if( $nodes ) {
					$scope->where("id=%d",$v['id'])->save(array("level" => $level, 'has_child'=>1, 'path' => $path.",".$v['id']));
					refresh($nodes, $level + 1, $path.",".$v['id'], $scope);
				} else {
					$scope->where("id=%d",$v['id'])->save(array("level" => $level, 'has_child'=>0, 'path' => $path.",".$v['id']));
				}
			}
		}
		
		// 更新所有子级
		refresh( array( $newData ), ++$pLevel, $parentPath, $scope);
		
		/*
		$data = array (
			$newData ['id'] 
		);
		
		$condition = array (
			"pid" => array (
					"in",
					&$data
			)
		);
		
		while ( $this->where ( $condition )->count () ) {
			
			$this->where ( $condition )->setField ( "level", ++ $pLevel );
			
			$data = $this->where ( $condition )->getField ( "id", true );
		}*/
		
		unset($newData['level']);
		
		unset($newData['has_child']);
		
		$this->data = $newData;
		
		return true;
	}
	
	/**
	 * 获得Option树列表
	 * @param unknown $id 当前节点id
	 * @param unknown $partner 合作商id
	 * @param unknown $field 字段列表
	 * @return array()
	 */
	public function getOptionTree($id, $partner, $field) {
		/*获得客户所有栏目*/
		$categoryOptions = array();
		$tree = $this->getTree(0, $partner, $field);
		/*去除当前节点*/
		function delNode($id, &$now){
			foreach($now as $k=>&$v){
				if($v["id"] == $id){
					unset($now[$k]);
					return;
				}else{
					if($v["_"]) delNode($id, $v["_"]);
				}
			}
		}
		$id && delNode($id, $tree);
		$categoryLists = $this->getTreeList($tree);
		foreach($categoryLists as $v) {
			$categoryOptions[$v['id']] = $v['tab'].$v['name'];
		}
		return $categoryOptions;
	}
	
} 